﻿namespace EasyToolkit.ModelDefinition
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using EasyToolkit.ModelDefinition.Definition.XmlDefinition;
    using EasyToolkit.Tools.Extensions;

    class ModelLinkProperty : IModelProperty 
    {
        #region properties and attributes
        public string Name
        { get; protected set; }

        public string Description
        { get; protected set; }

        public IModelType Parent
        { get; private set; }

        public string LinkTypeDefinition
        { get; private set; }

        public IModelType LinkType
        { get; private set; }

        public IEnumerable<string> Keys
        { get; private set; }
        #endregion

        #region .ctors and factoriez
        private ModelLinkProperty(IModelType parent, string name, string description, string linkTypeDefinition, IEnumerable<string> keys)
        {
            try
            {
                if (string.IsNullOrEmpty(name))
                    throw new EasyToolkitException("'Name' cannot be null or empty");

                Name = name;
                Description = description;

                Keys = keys;

                if (parent == null)
                    throw new EasyToolkitException("'Parent Type' is not defined");
                Parent = parent;

                if (string.IsNullOrEmpty(linkTypeDefinition))
                    throw new EasyToolkitException("'TypeDefinition' cannot be null or empty");
                LinkTypeDefinition = linkTypeDefinition;

                LinkType = ModelDefinitionManager.Instance.GetModelType(LinkTypeDefinition);
                if (LinkType == null)
                    throw new EasyToolkitException(string.Format("Cannot resolve linked definition '{0}'", LinkTypeDefinition.EmptyIfNull()));
            }
            catch (Exception ex)
            {
                throw new EasyToolkitException(string.Format("Type Property '{0}-{1}' creation failed: {2}", Parent == null ? string.Empty : Parent.Name.EmptyIfNull(),
                                                                                                             Name.EmptyIfNull(),
                                                                                                             ex.Message));
            }
        }

        static public IModelProperty CreateInstanceFromXmlDefinition(IModelType parent, XmlModelPropertyDefinition xmlDefinition)
        { 
            IModelProperty ret = null;
            if (xmlDefinition != null)
            {
                try
                {
                    IEnumerable<string> keys = null;
                    if (!string.IsNullOrEmpty(xmlDefinition.Keys))
                        keys = xmlDefinition.Keys.Split(',').Select(k => k.Trim()).Where(k => string.IsNullOrEmpty(k));
                    ret = new ModelLinkProperty(parent, xmlDefinition.Name, xmlDefinition.Description, xmlDefinition.TypeDefinition, keys);
                }
                catch(Exception ex)
                {
                    throw new EasyToolkitException(string.Format("Cannot create model property from xml: {0}", ex.Message));
                }
            }
            return ret;
        }
        #endregion
    }
}
